using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate;

namespace Dragoon.BreakIt
{

    namespace Data
    {
        public class Configuration
        {
            /// <summary>
            /// The size of the view
            /// </summary>            
            public Point View;
            /// <summary>
            /// The size of the block
            /// </summary>
            public Point Block;
            public BlockType[] BlockTypes;
            public CapsuleType[] CapsuleTypes;
            public Level[] Levels;
            public string ToXnaXml()
            {
                MemoryStream ms = new MemoryStream();
                XmlTextWriter w = new XmlTextWriter(ms, Encoding.UTF8);
                w.Formatting = Formatting.Indented;
                IntermediateSerializer.Serialize(w, this, "simple");
                w.Flush();
                ms.Seek(0, SeekOrigin.Begin);
                TextReader r = new StreamReader(ms);
                return r.ReadToEnd();
            }

            public static Configuration ParseFromFile(string xmlFileName)
            {
                Data.Configuration config = new Data.Configuration();
                XmlSerializer ser = new XmlSerializer(typeof(Data.Configuration));
                StreamReader s = new StreamReader(xmlFileName);
                return (Data.Configuration)ser.Deserialize(s.BaseStream);
            }

        }



    }

    public class Configuration
    {
        public readonly CapsuleTypeSet Capsules = new CapsuleTypeSet();
        public readonly BlockTypeSet BlockTypes = new BlockTypeSet();
        public readonly Rectangle PlayArea;
        public readonly List<Level> Levels;

        public static Configuration ParseFromFile(string xmlFileName)
        {
            return new Configuration(
                Data.Configuration.ParseFromFile(xmlFileName),null
                );
        }


        public Configuration(Data.Configuration data, Rectangle? innerPlayArea)
        {
            if (innerPlayArea.HasValue)
            {
                data.View.X = innerPlayArea.Value.Width;
                data.View.Y = innerPlayArea.Value.Height;
                PlayArea = innerPlayArea.Value;
                data.Block.X = PlayArea.Width / 20;
                data.Block.Y = PlayArea.Height / 20;
            }
            else
            {
                if (data.View == Point.Zero)
                    throw new ExDragoon("Configuration has zero view");
                PlayArea = new Rectangle(0, 0, data.View.X, data.View.Y);
            }
            Geometry.MaxY = PlayArea.Height;
            Geometry.MaxX = PlayArea.Width;

            foreach (Data.CapsuleType e in data.CapsuleTypes)
                Capsules.Add(new CapsuleType(e));
            foreach (Data.BlockType e in data.BlockTypes)
                BlockTypes.Add(new BlockType(e));
            Levels = new List<Level>();
            if (Levels == null || data.Levels.Length == 0)
                throw new ExDragoon("The configuration has no levels");
            foreach (Data.Level d in data.Levels)
            {
                if (d.Rows == null)
                    throw new ExDragoon("Level in input file has no rows");
                Levels.Add(new Level(d, BlockTypes,Capsules,
                    PlayArea,
                    data.Block));
            }
        }

    }
}
